home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Network Support Library
/
RoseWare - Network Support Library.iso
/
apidev
/
q_srvr.arc
/
Q1.PAS
next >
Wrap
Pascal/Delphi Source File
|
1989-09-07
|
22KB
|
1,042 lines
Program Queue_Server_Demo;
{
This is a Queue Server demo program.
This utility will create Queue (if it doesn't exist already) to be
serviced. As part of creating the Queue the user SUPERVISOR will be
added as a Q_SERVER...doing this requires the SUPERVISOR to be logged in
at the station performing the Queue functions...this is not the only way
to do this, another user could be used.
After the Queue is created it will be attached to and the Queue server
status will be set. This status is just an FYI field that can be used
to indicate whatever to the Queue's clients.
Next the Queue server will attempt to service a queue job if one exists.
For purposes of this demo the Queue Server will take the job and read it
as such:
byte 0 = logical station number
bytes 1..56 = message to send
Next the Queue server will finish servicing the queue job and attempt to
service another job.
If the human Queue Server user stops the Queue Server it will detach itself
from the queue it is servicing.
Note that up to 25 Queue Servers can service a single queue simultaneously.
note that this utility does not do extensive error checking, for instance,
if a bad file handle is returned on the open NETQ operation, this program
will be none the wiser...remember these routines are to show how to
perform basic queue server operations (a skeleton queue server if you will)
not how to perform comprehensive error checking...
by: John T. McCann
9/7/89
}
Uses Dos, Crt;
Type
char60 = array[0..60] of byte;
Long = record
a,b,c,d : byte;
end;
MyWord = record
wh,wl : byte
end;
e364c = record
native : MyWord;
func : byte; { will be 0x64, Create Queue }
Qtype : MyWord;
QnameL : byte;
Qname : array[1..4] of byte; { can be up to 47 }
{ for purposes here I am using }
{ the fixed name "DEMO" }
dirhnd : byte;
pathL : byte; { 1..118 }
pathN : array[1..20] of byte;
end;
e364r = record
native : MyWord;
Qid : Long;
end;
e335c = record
native : MyWord;
func : byte; { will be 0x35, Get an Object's Number }
objtyp : MyWord;
objnml : byte;
objnme : array[1..4] of byte; {DEMO}
end;
e335r = record
native : MyWord;
Qid : Long;
objtyp : MyWord;
objnme : array[1..48] of byte;
end;
e341c = record
native : MyWord;
func : byte; { will be 0x41, Add a member to a property set }
objtyp : MyWord;
objnml : byte;
objnme : array[1..4] of byte; { using name DEMO per above }
propl : byte;
propn : array[1..9] of byte; { Q_SERVERS }
memtyp : MyWord;
memnml : byte;
memnme : array[1..10] of byte; { SUPERVISOR }
end;
e341r = record
native : MyWord;
junk : byte;
end;
e341Ec = record
native : MyWord;
func : byte; { will be 0x41, Add a member to a property set }
objtyp : MyWord;
objnml : byte;
objnme : array[1..4] of byte; { using name DEMO per above }
propl : byte;
propn : array[1..7] of byte; { Q_USERS }
memtyp : MyWord;
memnml : byte;
memnme : array[1..8] of byte; { EVERYONE }
end;
e341Er = record
native : MyWord;
junk : byte;
end;
e36fc = record
native : MyWord;
func : byte; { will be 0x6F, Attach Queue Server to Queue }
Qid : Long;
end;
e36fr = record
native : MyWord;
junk : byte;
end;
e377c = record
native : MyWord;
func : byte; { will be 0x77, Set Queue Server Current Status }
Qid : Long;
charge : array[1..4] of byte;
status : string[59];
end;
e377r = record
native : MyWord;
junk : byte;
end;
e36bc = record
native : MyWord;
func : byte; { will be 0x6B, Get Queue Job List }
Qid : Long;
end;
e36br = record
native : MyWord;
jobcnt : MyWord;
jobnum : array[1..250] of MyWord; { actual length is based on }
{ jobcnt }
maxjnm : MyWord;
end;
e371c = record
native : MyWord;
func : byte; { will be 0x71, Service Queue Job and Open File }
Qid : Long;
Target : MyWord; { will be 0xFFFF, all job types }
end;
e371r = record
native : MyWord;
cltnst : byte;
clttnm : byte;
cltID : Long;
tsID : Long;
texect : array[1..6] of byte;
jobent : array[1..6] of byte;
jobnum : MyWord;
jobtyp : MyWord;
jobpos : byte;
jobcfl : byte;
jobfln : array[1..14] of byte;
jobflh : array[1..6] of byte;
srvstn : byte;
srvtsk : byte;
srvID : Long;
end;
e372c = record
native : MyWord;
func : byte; { will be 0x72, Finish Servicing Queue Job and File }
Qid : Long;
jobnum : MyWord;
charge : Long;
end;
e372r = record
native : MyWord;
junk : byte;
end;
e370c = record
native : MyWord;
func : byte; { will be 0x70, Detach Queue Server from Queue }
Qid : Long;
end;
e370r = record
native : MyWord;
junk : byte;
end;
e104c = record
native : MyWord;
func : byte; { will be 0, Send a Broadcast Message }
numstn : byte;
stnlst : byte; { can be more than 1, here though, only 1 }
meslen : byte;
messge : array[1..60] of byte;
end;
e104r = record
native : MyWord;
numstn : byte;
stnlst : byte; { can be more than 1, here though, only 1 }
end;
e336c = record
native : MyWord;
func : byte; { will be 0x36, Get an Object's Name }
objid : Long;
end;
e336r = record
native : MyWord;
Qid : Long;
objtyp : MyWord;
objnme : array[1..48] of byte;
end;
var
regs : registers;
CQc : e364c; { Create Queue }
CQr : e364r;
GIc : e335c; { Get an Object's ID }
GIr : e335r;
a2gc : e341c; { Add to (2) Group }
a2gr : e341r;
aE2gc : e341Ec;{ Add to (2) Group }
aE2gr : e341Er;{ Add group EVERYONE to Q_USERS }
AQc : e36fc; { Attach to Queue }
AQr : e36fr;
SSc : e377c; { Set queue Status }
SSr : e377r;
GLc : e36bc; { Get queue List }
GLr : e36br;
SJc : e371c; { Service queue Job }
SJr : e371r;
FJc : e372c; { Finish service of Job }
FJr : e372r;
DQc : e370c; { Detach from Queue }
DQr : e370r;
SMc : e104c; { Send Message }
SMr : e104r;
GNc : e336c; { Get Object Name }
GNr : e336r;
theQ : Long; { holds our Queue ID }
Queuetype : MyWord; { holds our Queue type }
a : integer;
{*-*-*-*-*-*-*-*-*-*-*-*-* Procedures below *-*-*-*-*-*-*-*-*-*-*-*-*}
Procedure DisplayError(code:byte; routine:byte);
Begin
Write('Error from ');
case routine of
1: Write('CreateQueue');
2: Write('AddSUPERVISOR');
3: Write('AttachQueue');
4: Write('SetStatus');
5: Write('GetList');
6: Write('ServiceJob');
7: Write('FinishJob');
8: Write('DetachQueue');
9: Write('AddEVERYONE');
10:Write('MessageBy');
end; { end of case }
Write('-> ');
case code of
$96: Writeln('Server out of memory');
$99: Writeln('Directory Full');
$9B: Writeln('Bad Directory Handle');
$9C: Writeln('Invalid Path');
$D0: Writeln('Queue Error');
$D1: Writeln('No Queue');
$D2: Writeln('No Queue server');
$D3: Writeln('No Queue rights');
$D5: Writeln('No Queue job');
$D6: Writeln('No Job rights');
$D9: Writeln('Station not server');
$DA: Writeln('Queue halted');
$DB: Writeln('Max Queue Servers reached');
$E9: Writeln('Member already exists in property');
$ED: Writeln('Property already exists');
$EE: Writeln('Object already exists');
$EF: Writeln('Invalid name');
$F0: Writeln('Wildcard not allowed');
$F1: Writeln('Invalid bindery security');
$F5: Writeln('No object create privilege');
$F7: Writeln('No propery create privilege');
$FC: Writeln('No such object');
$FE: Writeln('Server bindery locked');
$FF: Writeln('Bindery failure');
else Writeln('<',code,'> - ? Unknown ?');
end; { end of case }
End; { end of DisplayError }
Procedure CreateQueue;
Begin
with CQc do
begin
native.wh := 30;
native.wl := 0;
func := $64;
Qtype.wh := QueueType.wh; { Arbitrary }
Qtype.wl := QueueType.wl;
QnameL := 4;
Qname[1] := 68; {D}
Qname[2] := 69; {E}
Qname[3] := 77; {M}
Qname[4] := 79; {O}
dirhnd := 0; {0 means the full pathname will be specified minus servername}
pathL := 10;
pathN[1] := 83; {S}
pathN[2] := 89; {Y}
pathN[3] := 83; {S}
pathN[4] := 58; {:}
pathN[5] := 83; {S}
pathN[6] := 89; {Y}
pathN[7] := 83; {S}
pathN[8] := 84; {T}
pathN[9] := 69; {E}
pathN[10] := 77; {M}
end;
CQr.native.wh := 4;
CQr.native.wl := 0;
with regs do
begin
AX := $E300;
DS := Seg(CQc);
SI := Ofs(CQc);
ES := Seg(CQr);
DI := Ofs(CQr);
end;
MsDos(regs);
if (regs.AL <> 0) and (regs.AL <> 238) then DisplayError(regs.AL, 1);
if (regs.AL = 0) then
begin
theQ.a := CQr.Qid.a;
theQ.b := CQr.Qid.b;
theQ.c := CQr.Qid.c;
theQ.d := CQr.Qid.d;
end;
if (regs.AL = 238) then {Queue already exists, get its id}
begin
with GIc do
begin
native.wh := 8;
native.wl := 0;
func := $35;
objtyp.wh := QueueType.wh; { must match type defined in CreateQueue [above] }
objtyp.wl := QueueType.wl;
objnml := 4;
objnme[1] := 68; {D}
objnme[2] := 69; {E}
objnme[3] := 77; {M}
objnme[4] := 79; {O}
end;
GIr.native.wh := 54;
GIr.native.wl := 0;
with regs do
begin
AX := $E300;
DS := Seg(GIc);
SI := Ofs(GIc);
ES := Seg(GIr);
DI := Ofs(GIr);
end;
MsDos(regs);
{ presumed it worked }
theQ.a := GIr.Qid.a;
theQ.b := GIr.Qid.b;
theQ.c := GIr.Qid.c;
theQ.d := GIr.Qid.d;
end;
End; { end of CreateQueue }
Procedure AddSUPERVISOR;
Begin
With a2gc do
begin
native.wh := 31;
native.wl := 0;
func := $41;
objtyp.wh := QueueType.wh; { same as Qtype in CreateQueue }
objtyp.wl := QueueType.wl;
objnml := 4;
objnme[1] := 68; {D}
objnme[2] := 69; {E}
objnme[3] := 77; {M}
objnme[4] := 79; {O}
propl := 9;
propn[1] := 81; {Q}
propn[2] := 95; {_}
propn[3] := 83; {S}
propn[4] := 69; {E}
propn[5] := 82; {R}
propn[6] := 86; {V}
propn[7] := 69; {E}
propn[8] := 82; {R}
propn[9] := 83; {S}
memtyp.wh := 0;
memtyp.wl := 1; { regular USER type }
memnml := 10;
memnme[1] := 83; {S}
memnme[2] := 85; {U}
memnme[3] := 80; {P}
memnme[4] := 69; {E}
memnme[5] := 82; {R}
memnme[6] := 86; {V}
memnme[7] := 73; {I}
memnme[8] := 83; {S}
memnme[9] := 79; {O}
memnme[10]:= 82; {R}
end;
a2gr.native.wh:=1;
a2gr.native.wl:=0;
with regs do
begin
AX := $E300;
DS := Seg(a2gc);
SI := Ofs(a2gc);
ES := Seg(a2gr);
DI := Ofs(a2gr);
end;
MsDos(regs);
if (regs.AL <> 0) and (regs.AL <> 233) then DisplayError(regs.AL, 2);
{ 233 = Member already exists in property }
End; { end of AddSUPERVISOR }
Procedure AddEVERYONE;
Begin
With aE2gc do
begin
native.wh := 28;
native.wl := 0;
func := $41;
objtyp.wh := QueueType.wh; { same as Qtype in CreateQueue }
objtyp.wl := QueueType.wl;
objnml := 4;
objnme[1] := 68; {D}
objnme[2] := 69; {E}
objnme[3] := 77; {M}
objnme[4] := 79; {O}
propl := 7;
propn[1] := 81; {Q}
propn[2] := 95; {_}
propn[3] := 85; {U}
propn[4] := 83; {S}
propn[5] := 69; {E}
propn[6] := 82; {R}
propn[7] := 83; {S}
memtyp.wh := 0;
memtyp.wl := 2; { regular GROUP type }
memnml := 8;
memnme[1] := 69; {E}
memnme[2] := 86; {V}
memnme[3] := 69; {E}
memnme[4] := 82; {R}
memnme[5] := 89; {Y}
memnme[6] := 79; {O}
memnme[7] := 78; {N}
memnme[8] := 69; {E}
end;
aE2gr.native.wh:=1;
aE2gr.native.wl:=0;
with regs do
begin
AX := $E300;
DS := Seg(aE2gc);
SI := Ofs(aE2gc);
ES := Seg(aE2gr);
DI := Ofs(aE2gr);
end;
MsDos(regs);
if (regs.AL <> 0) and (regs.AL <> 233) then DisplayError(regs.AL, 9);
{ 233 = Member already exists in property }
End; { end of AddEVERYONE }
Procedure AttachQueue;
Begin
with AQc do
begin
native.wh := 5;
native.wl := 0;
func := $6F;
Qid.a := theQ.a;
Qid.b := theQ.b;
Qid.c := theQ.c;
Qid.d := theQ.d;
end;
AQr.native.wh := 1;
AQr.native.wl := 0;
with regs do
begin
AX := $E300;
DS := Seg(AQc);
SI := Ofs(AQc);
ES := Seg(AQr);
DI := Ofs(AQr);
end;
MsDos(regs);
if (regs.AL <> 0) then DisplayError(regs.AL, 3)
else
Writeln('Successfully Attached to Queue DEMO');
End; { end of AttachQueue }
Procedure SetStatus;
Begin
with SSc do
begin
native.wh := 69;
native.wl := 0;
func := $77;
Qid.a := theQ.a;
Qid.b := theQ.b;
Qid.c := theQ.c;
Qid.d := theQ.d;
charge[1] := 0;
charge[2] := 0;
charge[3] := 0;
charge[4] := 0;
status := 'This is a demo Queue Server';
end;
SSr.native.wh := 1;
SSr.native.wl := 0;
with regs do
begin
AX := $E300;
DS := Seg(SSc);
SI := Ofs(SSc);
ES := Seg(SSr);
DI := Ofs(SSr);
end;
MsDos(regs);
if (regs.AL <> 0) then DisplayError(regs.AL, 4);
End; { end of SetStatus }
Procedure GetList;
Begin
with GLc do
begin
native.wh := 5;
native.wl := 0;
func := $6B;
Qid.a := theQ.a;
Qid.b := theQ.b;
Qid.c := theQ.c;
Qid.d := theQ.d;
end;
GLr.native.wh := $F8;
GLr.native.wl := $01; {504 or 0x1F8}
with regs do
begin
AX := $E300;
DS := Seg(GLc);
SI := Ofs(GLc);
ES := Seg(GLr);
DI := Ofs(GLr);
end;
MsDos(regs);
if (regs.AL <> 0) then DisplayError(regs.AL, 5);
End; { end of GetList }
Procedure FinishJob(jobnumber:MyWord);FORWARD;
Procedure MessageBy(submit:Long);FORWARD;
Procedure SendMessage(request:char60; len:integer);FORWARD;
Procedure ServiceJob;
var
NETQ : string[5];
request : char60;
a : integer;
filehan : integer;
bytes2read : integer;
Begin
with SJc do
begin
native.wh := 7;
native.wl := 0;
func := $71;
Qid.a := theQ.a;
Qid.b := theQ.b;
Qid.c := theQ.c;
Qid.d := theQ.d;
Target.wh := $FF;
Target.wl := $FF;
end;
SJr.native.wh := 54;
SJr.native.wl := 0;
with regs do
begin
AX := $E300;
DS := Seg(SJc);
SI := Ofs(SJc);
ES := Seg(SJr);
DI := Ofs(SJr);
end;
MsDos(regs);
if (regs.AL <> 213) then { no queue job, this will occur when someone opens
{ a queue job but hasn't closed it yet...}
Writeln;
if (regs.AL <> 213) then { repeated because I'd rather not indent some more...! }
if (regs.AL <> 0) then DisplayError(regs.AL, 6)
else
begin
with SJr do
Writeln('Job Submitted by ID [',cltID.a,'][',cltID.b,'][',cltID.c,'][',cltID.d,']');
MessageBy(SJr.cltID);
regs.AX := $3D02;
NETQ := 'NETQ'^@;
regs.DS := Seg(NETQ);
regs.DX := Ofs(NETQ)+1;
MsDos(regs);
Writeln('File Handle from open NETQ = [',regs.AX,']');
filehan := regs.AX;
bytes2read := 57;
regs.AX := $3F00;
regs.BX := filehan;
regs.CX := bytes2read;
regs.DS := Seg(request);
regs.DX := Ofs(request);
MsDos(regs);
{
byte 0 = logical station number to send to
bytes 1..56 = message to send
}
if (regs.AX > 1) then
SendMessage(request,regs.AX)
else
Writeln('Job is of 0 length, nothing to process...');
regs.AX := $3E00;
regs.BX := filehan;
MsDos(regs);
FinishJob(SJr.jobnum);
end;
End; { end of ServiceJob }
Procedure MessageBy;
var
a : integer;
Begin
with GNc do
begin
native.wh := 5;
native.wl := 0;
func := $36;
objid.a := submit.a;
objid.b := submit.b;
objid.c := submit.c;
objid.d := submit.d;
end;
GNr.native.wh := 54;
GNr.native.wl := 0;
with regs do
begin
AX := $E300;
DS := Seg(GNc);
SI := Ofs(GNc);
ES := Seg(GNr);
DI := Ofs(GNr);
end;
MsDos(regs);
if (regs.AL <> 0) then DisplayError(regs.AL, 10)
else
begin
Write('Processing job from: [');
regs.AX := $0900;
regs.DS := Seg(GNr.objnme);
regs.DX := Ofs(GNr.objnme);
for a:=1 to 48 do
if (GNr.objnme[a]=0) then GNr.objnme[a] := ord('$');
MsDos(regs);
Writeln(']');
end;
End; { end of MessageBy }
Procedure SendMessage;
var
a : integer;
Begin
if (len>57) then len:=57;
with SMc do
begin
native.wh := 4+len-1;
native.wl := 0;
func := 0;
numstn := 1;
meslen := len-1;
stnlst := request[0];
a:=1;
while (a<(len)) do
begin
if (request[a]<>0) then messge[a] := request[a]
else
begin
meslen := a-1;
native.wh := 4+meslen;
end;
a:=a+1;
end;
end;
SMr.native.wh := 2;
SMr.native.wl := 0;
with regs do
begin
AX := $E100;
DS := Seg(SMc);
SI := Ofs(SMc);
ES := Seg(SMr);
DI := Ofs(SMr);
end;
MsDos(regs);
if (regs.AL <> 0) then Write('Unable to send message ')
else
Write('Message sent ');
Writeln('to station [',request[0],']');
End; { end of SendMessage }
Procedure FinishJob;
Begin
with FJc do
begin
native.wh := 11;
native.wl := 0;
func := $72;
Qid.a := theQ.a;
Qid.b := theQ.b;
Qid.c := theQ.c;
Qid.d := theQ.d;
jobnum.wh := jobnumber.wh;
jobnum.wl := jobnumber.wl;
charge.a := 0;
charge.b := 0;
charge.c := 0;
charge.d := 0;
end;
FJr.native.wh := 1;
FJr.native.wl := 0;
with regs do
begin
AX := $E300;
DS := Seg(FJc);
SI := Ofs(FJc);
ES := Seg(FJr);
DI := Ofs(FJr);
end;
MsDos(regs);
if (regs.AL <> 0) then DisplayError(regs.AL, 7);
End; { end of FinishJob }
Procedure DetachQueue;
Begin
with DQc do
begin
native.wh := 5;
native.wl := 0;
func := $70;
Qid.a := theQ.a;
Qid.b := theQ.b;
Qid.c := theQ.c;
Qid.d := theQ.d;
end;
DQr.native.wh := 1;
DQr.native.wl := 0;
with regs do
begin
AX := $E300;
DS := Seg(DQc);
SI := Ofs(DQc);
ES := Seg(DQr);
DI := Ofs(DQr);
end;
MsDos(regs);
if (regs.AL <> 0) then DisplayError(regs.AL, 8)
else
Writeln('Successfully detached from Queue DEMO');
End; { end of DetachQueue }
Begin
QueueType.wh := 3;
QueueType.wl := 3; { this is an arbitrary queue type... 0x0303 }
clrscr;
CreateQueue;
Writeln('Qid is [',theQ.a,'][',theQ.b,'][',theQ.c,'][',theQ.d,']');
AddSUPERVISOR;
AddEVERYONE;
AttachQueue;
SetStatus;
repeat
GetList;
Write('Number of jobs in queue [',GLr.jobcnt.wl,']');
if (GLr.jobcnt.wl>0) then
begin
ServiceJob;
if (regs.AL = 213) then for a:=1 to 40 do write(#8)
else
writeln('─────» end of job processing «─────');
end
else
for a:=1 to 40 do write(#8);
delay(1000*15); { 15 second delay, you can vary this... }
until keypressed;
DetachQueue;
End.